﻿
/**
------------------------------------------------------------
* NGUYEN SY BACH
* bit.mta@gmail.com
* Hoc Vien Ky Thuat Quan Su
------------------------------------------------------------
*** Source ho tro doc anh bitmap
------------------------------------------------------------
*/

#include <Windows.h>
#include "nsb_helper_readbmp.h"


//------------ Lấy một mẩu ảnh------------
// headerSize: kích thước phần header
// r0: là tọa độ hàng của mẩu
// c0: là tọa độ cột của mẩu
// rows: kích thước hàng
// cols: kích thước cột
// bytesPerPixel: số lượng bytes cho một pixel
// rowLength: số bytes trên một hàng ảnh
// outPtr: con trỏ đầu ra
void DocMauAnh(FILE* filePtr, BYTE headerSize,
	int r0, int c0, int rows, int cols, int bytesPerPixel,
	int rowLength, BYTE* &outPtr){
	HANDLE_NULL(outPtr);
	BYTE* ptr = outPtr;
	//Thực hiện đọc từng hàng ảnh
	fseek(filePtr, headerSize + r0 *rowLength + c0*bytesPerPixel, SEEK_SET);
	for (int i = 0; i < rows; ++i){
		fread(ptr, sizeof(BYTE), cols*bytesPerPixel, filePtr);
		ptr += cols*bytesPerPixel;
		fseek(filePtr, rowLength - cols*bytesPerPixel, SEEK_CUR);
	}
}

bool DocPhanHeader(FILE *filePtr, int &width, int &height, int &depth,
	int &rowLength, int &headerSize){
	//Đọc phần header file
	BITMAPFILEHEADER bmfh;
	int soByteDocDuoc = 0;
	soByteDocDuoc = (int)fread(&bmfh, sizeof(BITMAPFILEHEADER), 1, filePtr);
	if (soByteDocDuoc != 1 ||
		bmfh.bfType != *(WORD*)"BM"){
		fprintf(stderr, "Khong the duoc file, hoac file sai dinh dang.\n");
		fclose(filePtr);
		return false;
	}

	// kích thước phần thông tin ảnh và dữ liệu ảnh
	int infoSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
	// Đọc phần header ảnh
	BITMAPINFO* pbmi = NULL;
	pbmi = (BITMAPINFO*)malloc(infoSize);
	HANDLE_NULL(pbmi);
	soByteDocDuoc = (int)fread(pbmi, sizeof(BITMAPINFO), 1, filePtr);
	if (soByteDocDuoc != 1){
		fprintf(stderr, "Khong the duoc file, hoac file sai dinh dang.\n");
		fclose(filePtr);
		return false;
	}
	// Tính chiều dài , chiều rộng
	// số lượng bytes trên một hàng ảnh
	width = pbmi->bmiHeader.biWidth;
	height = pbmi->bmiHeader.biHeight;
	depth = pbmi->bmiHeader.biBitCount;
	rowLength = ((width * depth + 31) & ~31) >> 3;
	headerSize = sizeof(BITMAPFILEHEADER)+infoSize;
	return true;
}
